//
//  HEMediaManager.m
//  HealthFamily
//
//  Created by 吴欧 on 2020/11/28.
//  Copyright © 2020 honglutec. All rights reserved.
//

#import "HEMediaManager.h"
#import "HEIMMessageCell.h"
#import <AVFoundation/AVFoundation.h>

@interface HEMediaManager ()

@property (nonatomic, weak) id<HEIMMediaManagerDelegate> delegate;

@property (nonatomic, strong) NSMapTable <id, id<HEIMMediaManagerDelegate>> *objectInfosMap;

@property (nonatomic, assign) BOOL isPlaying;

@property (nonatomic, strong) AVPlayer *player;

@property (nonatomic, strong) AVPlayerItem *songitem;

@end

@implementation HEMediaManager

#pragma mark - LifeCycle
+(instancetype)sharedManager {
    static dispatch_once_t onceToken;
    static HEMediaManager *instance;
    dispatch_once(&onceToken, ^{
        instance = [[HEMediaManager alloc] init];
        
        instance.objectInfosMap = [[NSMapTable alloc] initWithKeyOptions:NSPointerFunctionsStrongMemory|NSPointerFunctionsObjectPointerPersonality valueOptions:NSPointerFunctionsStrongMemory|NSPointerFunctionsObjectPersonality capacity:0];

//        instance.objectInfosMap = [NSMapTable mapTableWithKeyOptions:NSMapTableWeakMemory|NSPointerFunctionsObjectPointerPersonality valueOptions:NSMapTableWeakMemory|NSPointerFunctionsObjectPersonality];
    });
    return instance;
}

- (void)addDelegate:(id<HEIMMediaManagerDelegate>)delegate {
    HEIMMessageCell *cell = (HEIMMessageCell *)delegate;
    [self.objectInfosMap setObject:delegate forKey:cell.model.message];
}

- (void)removeAllDelegate {
    [self.objectInfosMap removeAllObjects];
}
 
- (void)playByMessage:(HEIMMessage *)message {
     
    id<HEIMMediaManagerDelegate> delegate = [self.objectInfosMap objectForKey: message];
    
    // 是否是同一个语音消息
    if (message == _currentPlayingMessage) {
        if (_isPlaying) {
            [self stopPlayUI];
        }else {
            [self startPlayUI: delegate message: message];
        }
    }else {
        // 停止上一个音频文件
        if (_currentPlayingMessage) {
            [self stopPlayUI];
        }
        [self startPlayUI: delegate message: message];
    }
}

// 扬声器模式
- (void)setAudioWaiFangSession
{
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    //设置为播放
    [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionDefaultToSpeaker error:nil];

    [audioSession setActive:YES error:nil];
}

- (void)stopPlay {
    if (_currentPlayingMessage) {
        [self stopPlayUI];
    }
}

- (void)startPlayUI:(id<HEIMMediaManagerDelegate>)delegate message:(HEIMMessage *)message {
    [delegate playAudio:nil didBeganWithError:nil];
    self.isPlaying = YES;
    _currentPlayingMessage = message;
    
    [self startPlay];
}
 
- (void)stopPlayUI {
    
    [self.player pause];
    
    id<HEIMMediaManagerDelegate> delegate = [self.objectInfosMap objectForKey: _currentPlayingMessage];
    [delegate stopPlayAudio:nil didCompletedWithError:nil];
    self.isPlaying = NO;
    _currentPlayingMessage = nil;
}

- (void)startPlay {
     
    [self setAudioWaiFangSession];
    
    HEIMAudioObject *audio = (HEIMAudioObject *)_currentPlayingMessage.messageObject;
     
    // 本地录音资源文件
    NSURL *url = [NSURL fileURLWithPath: audio.url];
    
    // 网络录音资源文件
    if ([audio.url hasPrefix:@"http://"] || [audio.url hasPrefix:@"https://"]) {
        url = [NSURL URLWithString: audio.url];
    }
    
    _songitem = [[AVPlayerItem alloc] initWithURL:url];
    self.player = [[AVPlayer alloc] initWithPlayerItem: _songitem];

    [_songitem addObserver:self forKeyPath:@"status" options:NSKeyValueObservingOptionNew context:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackFinished:) name:AVPlayerItemDidPlayToEndTimeNotification object: _songitem]; 
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context {
    if ([keyPath isEqualToString:@"status"]) {
        // 取出status的新值
        AVPlayerItemStatus status = [change[NSKeyValueChangeNewKey] intValue];
        switch (status) {
            case AVPlayerItemStatusFailed: {
                [Dialog toastBottom:@"未知错误，不能播放"];

            } break;
            case AVPlayerItemStatusReadyToPlay: {
                [self.player play];
                 
            } break;
            case AVPlayerItemStatusUnknown: {
                [Dialog toastBottom:@"加载失败，网络或者服务器出现问题"];

            } break;
            default: break;
        }
    }
}

- (void)playbackFinished:(NSNotification *)notice {
    [self stopPlayUI];
    [self removeNotif];
}

- (void)removeNotif {
    if (_songitem) {
        [_songitem removeObserver:self forKeyPath:@"status"];
    }
    [[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:_songitem];
}

@end
